/*
 * Unidata Platform Community Edition
 * Copyright (c) 2013-2020, UNIDATA LLC, All rights reserved.
 * This file is part of the Unidata Platform Community Edition software.
 *
 * Unidata Platform Community Edition is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Unidata Platform Community Edition is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */

package org.unidata.mdm.data.service;

import java.util.List;

import org.unidata.mdm.core.type.timeline.Timeline;
import org.unidata.mdm.data.context.DeleteRelationRequestContext;
import org.unidata.mdm.data.context.DeleteRelationsRequestContext;
import org.unidata.mdm.data.context.GetRelationRequestContext;
import org.unidata.mdm.data.context.GetRelationsDigestRequestContext;
import org.unidata.mdm.data.context.GetRelationsRequestContext;
import org.unidata.mdm.data.context.GetRelationsTimelineRequestContext;
import org.unidata.mdm.data.context.MergeFromRelationRequestContext;
import org.unidata.mdm.data.context.MergeRelationsRequestContext;
import org.unidata.mdm.data.context.MergeToRelationRequestContext;
import org.unidata.mdm.data.context.RestoreFromRelationRequestContext;
import org.unidata.mdm.data.context.RestoreRelationsRequestContext;
import org.unidata.mdm.data.context.RestoreToRelationRequestContext;
import org.unidata.mdm.data.context.UpsertRelationRequestContext;
import org.unidata.mdm.data.context.UpsertRelationsRequestContext;
import org.unidata.mdm.data.dto.DeleteRelationDTO;
import org.unidata.mdm.data.dto.DeleteRelationsDTO;
import org.unidata.mdm.data.dto.GetRelationDTO;
import org.unidata.mdm.data.dto.GetRelationsDTO;
import org.unidata.mdm.data.dto.MergeRelationDTO;
import org.unidata.mdm.data.dto.MergeRelationsDTO;
import org.unidata.mdm.data.dto.RelationDigestDTO;
import org.unidata.mdm.data.dto.RelationsBulkResultDTO;
import org.unidata.mdm.data.dto.RestoreRelationDTO;
import org.unidata.mdm.data.dto.RestoreRelationsDTO;
import org.unidata.mdm.data.dto.UpsertRelationDTO;
import org.unidata.mdm.data.dto.UpsertRelationsDTO;
import org.unidata.mdm.data.type.apply.batch.impl.RelationDeleteBatchSetAccumulator;
import org.unidata.mdm.data.type.apply.batch.impl.RelationMergeBatchSetAccumulator;
import org.unidata.mdm.data.type.apply.batch.impl.RelationRestoreBatchSetAccumulator;
import org.unidata.mdm.data.type.apply.batch.impl.RelationUpsertBatchSetAccumulator;
import org.unidata.mdm.data.type.data.OriginRelation;

/**
 * @author Mikhail Mikhailov on Dec 3, 2019
 */
public interface DataRelationsService {
    /**
     * Loads relevant relations time line for the given relation identities and relation name.
     *
     * @param ctx the context
     * @return timeline
     */
    List<Timeline<OriginRelation>> loadTimelines(GetRelationsRequestContext ctx);
    /**
     * Loads relevant relations time lines for the given record identities and relation name.
     *
     * @param ctx the context
     * @return timeline
     */
    List<Timeline<OriginRelation>> loadTimelines(GetRelationsTimelineRequestContext ctx);
    /**
     * Loads a relation by its etalon or origin id.
     *
     * @param ctx the context
     * @return relation
     */
    GetRelationDTO getRelation(GetRelationRequestContext ctx);
    /**
     * Gets relations by simple request contexts.
     *
     * @param ctxts the contexts
     * @return relations DTO
     */
    List<GetRelationDTO> getRelations(List<GetRelationRequestContext> ctxts);
    /**
     * Gets the relations.
     * @param ctx the context
     * @return relations DTO
     */
    GetRelationsDTO getRelations(GetRelationsRequestContext ctx);
    /**
     * Upsert relation call.
     *
     * @param ctx the context
     * @return result (inserted/updated record)
     */
    UpsertRelationDTO upsertRelation(UpsertRelationRequestContext ctx);
    /**
     * Upsert multiple updating relations call.
     *
     * @param ctxts the contexts to process
     * @return result (inserted/updated record)
     */
    List<UpsertRelationDTO> upsertRelations(List<UpsertRelationRequestContext> ctxts);
    /**
     * Upsert relations call.
     *
     * @param ctx the context
     * @return result (inserted/updated records)
     */
    UpsertRelationsDTO upsertRelations(UpsertRelationsRequestContext ctx);
    /**
     * Deletes a relation.
     *
     * @return result DTO
     */
    DeleteRelationDTO deleteRelation(DeleteRelationRequestContext ctx);
    /**
     * Deletes relations.
     *
     * @param ctxts the contexts
     * @return result DTO
     */
    List<DeleteRelationDTO> deleteRelations(List<DeleteRelationRequestContext> ctxts);
    /**
     * Deletes possibly multiple relations.
     *
     * @return result DTO
     */
    DeleteRelationsDTO deleteRelations(DeleteRelationsRequestContext ctx);
    /**
     * Merges 'From" directed relation.
     * @param ctx the context
     * @return result
     */
    MergeRelationDTO mergeRelation(MergeFromRelationRequestContext ctx);
    /**
     * Merges 'To" directed relation.
     * @param ctx the context
     * @return result
     */
    MergeRelationDTO mergeRelation(MergeToRelationRequestContext ctx);
    /**
     * Merges a number of relations (from + to, processAll, selected relation names, etc.).
     * @param ctx the context
     * @return result
     */
    MergeRelationsDTO mergeRelations(MergeRelationsRequestContext ctx);
    /**
     * Restores 'From" directed relation.
     * @param ctx the context
     * @return result
     */
    RestoreRelationDTO restore(RestoreFromRelationRequestContext ctx);
    /**
     * Restores 'To" directed relation.
     * @param ctx the context
     * @return result
     */
    RestoreRelationDTO restore(RestoreToRelationRequestContext ctx);
    /**
     * Restores a number of relations (from + to, processAll, selected relation names, etc.).
     * @param ctx the context
     * @return result
     */
    RestoreRelationsDTO restore(RestoreRelationsRequestContext ctx);
    /**
     * Collects and returns relation's digest according to the request context.
     *
     * @param ctx request context
     * @return result
     */
    RelationDigestDTO loadRelatedEtalonIdsForDigest(GetRelationsDigestRequestContext ctx);
    /**
     * Batch upsert relations with default accumulator context.
     * @param ctxs contexts for update
     * @return update result
     */
    RelationsBulkResultDTO batchUpsertRelations(List<UpsertRelationsRequestContext> ctxs);
    /**
     * Batch upsert relations with default accumulator context.
     * @param ctxs contexts for update
     * @param abortOnFailure abort on first failure
     * @return update result
     */
    RelationsBulkResultDTO batchUpsertRelations(List<UpsertRelationsRequestContext> ctxs, boolean abortOnFailure);
    /**
     * Batch upsert relations.
     * @param accumulator accumulator
     * @return result
     */
    RelationsBulkResultDTO batchUpsertRelations(RelationUpsertBatchSetAccumulator accumulator);
    /**
     * Batch delete relations with default accumulator context.
     * @param ctxs contexts for delete
     * @return delete result
     */
    RelationsBulkResultDTO batchDeleteRelations(List<DeleteRelationsRequestContext> ctxs);
    /**
     * Batch delete relations with default accumulator context.
     * @param ctxs contexts for delete
     * @param abortOnFailure abort on first failure
     * @return delete result
     */
    RelationsBulkResultDTO batchDeleteRelations(List<DeleteRelationsRequestContext> ctxs, boolean abortOnFailure);
    /**
     * Deletes relations in batched fashion.
     * @param accumulator accumulator
     * @return list of results
     */
    RelationsBulkResultDTO batchDeleteRelations(RelationDeleteBatchSetAccumulator accumulator);
    /**
     * Batch merge relations with default accumulator context.
     * @param ctxs contexts to merge
     * @return merge result
     */
    RelationsBulkResultDTO batchMergeRelations(List<MergeRelationsRequestContext> ctxs);
    /**
     * Batch merge relations with default accumulator context.
     * @param ctxs contexts to merge
     * @param abortOnFailure abort on first failure
     * @return merge result
     */
    RelationsBulkResultDTO batchMergeRelations(List<MergeRelationsRequestContext> ctxs, boolean abortOnFailure);
    /**
     * Merges relations in batched fashion.
     * @param accumulator accumulator
     * @return list of results
     */
    RelationsBulkResultDTO batchMergeRelations(RelationMergeBatchSetAccumulator accumulator);
    /**
     * Batch restore relations with default accumulator context.
     * @param ctxs contexts to merge
     * @return restore result
     */
    RelationsBulkResultDTO batchRestoreRelations(List<RestoreRelationsRequestContext> ctxs);
    /**
     * Batch merge relations with default accumulator context.
     * @param ctxs contexts to merge
     * @param abortOnFailure abort on first failure
     * @return merge result
     */
    RelationsBulkResultDTO batchRestoreRelations(List<RestoreRelationsRequestContext> ctxs, boolean abortOnFailure);
    /**
     * Merges relations in batched fashion.
     * @param accumulator accumulator
     * @return list of results
     */
    RelationsBulkResultDTO batchRestoreRelations(RelationRestoreBatchSetAccumulator accumulator);
}
